<html>
<head><meta charset="utf-8"><title>stacked borrows and data races · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20and.20data.20races.html">stacked borrows and data races</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="192415176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20and%20data%20races/near/192415176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20and.20data.20races.html#192415176">(Mar 31 2020 at 16:34)</a>:</h4>
<p>Copying the discussion at <a href="https://github.com/rust-lang/rust/issues/70598" title="https://github.com/rust-lang/rust/issues/70598">#70598</a> here to discuss further:</p>
<p><a href="https://github.com/vakeras" title="https://github.com/vakeras"><code>@vakeras</code></a> <a href="https://github.com/rust-lang/rust/pull/70598#issuecomment-606681190" title="https://github.com/rust-lang/rust/pull/70598#issuecomment-606681190">asked</a> on github:</p>
<blockquote>
<p>By the way, do stacked borrows rule out data-races except on UnsafeCell?</p>
</blockquote>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> <a href="https://github.com/rust-lang/rust/pull/70598#issuecomment-606685238" title="https://github.com/rust-lang/rust/pull/70598#issuecomment-606685238">responded</a>:</p>
<blockquote>
<p>With raw pointers it is possible to create data-races even with stacked borrows.</p>
</blockquote>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> <a href="https://github.com/rust-lang/rust/pull/70598#issuecomment-606685692" title="https://github.com/rust-lang/rust/pull/70598#issuecomment-606685692">responded</a>:</p>
<blockquote>
<p>If you also exclude raw pointers (as pointed out by @bjorn3), I think so, but have not formally proven it.</p>
</blockquote>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> <a href="https://github.com/rust-lang/rust/pull/70598#issuecomment-606731103" title="https://github.com/rust-lang/rust/pull/70598#issuecomment-606731103">responded</a>:</p>
<blockquote>
<p>@RalfJung I may be wrong with my understanding of stacked borrows, but I don't think stacked borrows rules out data races:</p>
<p>```rust<br>
fn main() {<br>
    // First create a mutable reference to some memory.<br>
    let ref1: &amp;'static /<em>0</em>/ mut u8 = Box::leak(Box::new(42u8));<br>
    // alloc0: Unique(0)</p>
<div class="codehilite"><pre><span></span>// Then derive a new mutable reference from the previous reference without borrowck knowing about it.
// alloc0: Unique(0)
let ref2: &amp;&#39;static /*1*/ mut u8 = unsafe { std::mem::transmute::&lt;&amp;&#39;_ mut u8, &amp;&#39;static mut u8&gt;(&amp;mut *ref1) };
// alloc0: Unique(0) Unique(1)

// Next write using one of the references from a new thread.
std::thread::spawn(move || {
    // alloc0: Unique(0) Unique(1)
    *ref2 = 0;
    // alloc0: Unique(0) Unique(1)
});

// Ensure the new thread runs first, so `Unique(1)` doesn&#39;t get popped before the new thread runs.
std::thread::sleep_ms(10);

// Finally write using the other reference in the current thread.
// Both writes happened without synchronization, so this is a data race.
// alloc0: Unique(0) Unique(1)
*ref1 = 1;
// alloc0: Unique(0)
println!(&quot;{}&quot;, ref1);
</pre></div>


<p>}<br>
```</p>
</blockquote>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> Finally <a href="https://github.com/rust-lang/rust/pull/70598#issuecomment-606733368" title="https://github.com/rust-lang/rust/pull/70598#issuecomment-606733368">responded</a>:</p>
<blockquote>
<p>@bjorn3 this is getting off-topic, but this is still UB as the first thread might take longer than 10ms to spawn. So the execution where *ref1 = 1 happens first is still possible, and then *ref2 = 0 fails because the item is not on the stack any more.</p>
<p>Let's continue this elsewhere though.</p>
</blockquote>



<a name="192415938"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20and%20data%20races/near/192415938" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20and.20data.20races.html#192415938">(Mar 31 2020 at 16:41)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> I guess you are right. I can't think of a way to never pop the item before it is used in the other thread without synchronization.</p>



<a name="192464598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20and%20data%20races/near/192464598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> comex <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20and.20data.20races.html#192464598">(Mar 31 2020 at 23:06)</a>:</h4>
<p>You can do it using a relaxed atomic, which communicates information from one thread to another without fully synchronizing them.</p>



<a name="192490944"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked%20borrows%20and%20data%20races/near/192490944" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/stacked.20borrows.20and.20data.20races.html#192490944">(Apr 01 2020 at 07:20)</a>:</h4>
<p>I am not sure if being able to communicate information is sufficient for the race, though</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>